#include <stdio.h>
#include "ArrayList.h"

extern "C" void __gxx_personality_sj0(void) {}
extern "C" void _Unwind_SjLj_Register(void) {}
extern "C" void _Unwind_SjLj_Resume(void) {}
void __builtin_trap(void) {
  while(1);
}


void *operator new (size_t size){
  //printf("new: %d\r\n", size);
  void* p = malloc(size);
  // for(int i=0;i<(size+1)<<2;i++){
  //   p[i] = 0;
  // }
  return p;
}
void operator delete(void* ptr, unsigned int size){
  free(ptr);
}

ArrayList::ArrayList(){
  size = 64;
  list = (void**)malloc(size * 4);
  length = 0;
}

// ArrayList::ArrayList(int size){
//   list = (int*)malloc(size * 4);
//   length = 0;
// }

ArrayList::~ArrayList(){
  free(list);
}

int ArrayList::push(void* obj){
  if(length >= size){
    int newSize = size<<1;
    void** newlist = (void**)malloc(newSize<<2);
    for(int i=0;i<length;i++){
      newlist[i] = list[i];
    }
    free(list);
    list = newlist;
    size = newSize;
  }
  list[length] = obj;
  int pos = length;
  length++;
  return pos;
}

void* ArrayList::get(int idx){
  return (void*)list[idx];
}

void* ArrayList::remove(int idx){
  void* ret = (void*)(list[idx]);
  for(int i=idx;i<length-1;i++){
    list[i] = list[i+1];
  }
  length--;
  if(length < size>>1){
    int newSize = size>>1;
    void** newlist = (void**)malloc(newSize<<2);
    for(int i=0;i<length;i++){
      newlist[i] = list[i];
    }
    free(list);
    list = newlist;
    size = newSize;
  }
  return ret;
}

int ArrayList::remove(void* obj){

  int ret = -1;
  for(int i=0;i<length;i++){
    if(obj == list[i]){
      ret = i;
    }
  }
  if(ret>=0){
    for(int i=ret;i<length-1;i++){
      list[i] = list[i+1];
    }
    length--;
    if(length < size>>1){
      int newSize = size>>1;
      void** newlist = (void**)malloc(newSize<<2);
      for(int i=0;i<length;i++){
        newlist[i] = list[i];
      }
      free(list);
      list = newlist;
      size = newSize;
    }
    return ret;
  }else{
    return -1;
  }
}
